package br.ufpe.cin.rgms.base.linhapesquisa.controller;

import java.util.List;

import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.ValidationMessage;
import br.ufpe.cin.rgms.base.linhapesquisa.dao.LinhaPesquisaDAO;
import br.ufpe.cin.rgms.base.linhapesquisa.model.LinhaPesquisa;
import br.ufpe.cin.rgms.base.membro.dao.MembroDAO;
import br.ufpe.cin.rgms.base.membro.model.Membro;

@Resource
public class LinhaPesquisaController {

	private LinhaPesquisaDAO dao;
	private MembroDAO membroDao;

	private Result result;
	private Validator validator;

	public LinhaPesquisaController(LinhaPesquisaDAO dao, MembroDAO membroDao,
			Result result, Validator validator) {
		this.dao = dao;
		this.result = result;
		this.validator = validator;
		this.membroDao = membroDao;
	}

	public void form() {
		result.include("membroList", membroDao.findAll());
	}

	public List<LinhaPesquisa> index(LinhaPesquisa linhaPesquisa) {
		List<LinhaPesquisa> linhas = null;
		if (linhaPesquisa != null) {
			linhas = dao.findAllByFilter(linhaPesquisa);
			if (linhas.isEmpty()) {
				result.include("mensagem", "linha_nao_encontrada");
			}
		}
		return linhas;
	}

	public LinhaPesquisa detalhe(Integer id) {
		result.include("membroList", membroDao.findByResearchLine(id));
		return dao.carrega(id);
	}

	public void remove(LinhaPesquisa linhaPesquisa) {
		if (linhaPesquisa != null) {
			linhaPesquisa = dao.carrega(linhaPesquisa.getId());
			dao.delete(linhaPesquisa);
			result.include("mensagem", "linha_excluida");
		}
		result.redirectTo(this).index(null);
	}

	public void adiciona(final LinhaPesquisa linhaPesquisa,
			final List<String> membros) {
		if (linhaPesquisa != null) {
			validaCamposObrigatorios(linhaPesquisa);
			validator.onErrorRedirectTo(this).form();

			dao.salva(linhaPesquisa);

			if (membros != null) {

				for (String id : membros) {
					Membro membro = membroDao.carrega(Integer.parseInt(id));
					membro.setLinhaPesquisa(linhaPesquisa);
					membroDao.altera(membro);
				}
			}

			result.include("mensagem", "linha_inserida");
			result.redirectTo(this).index(null);
		}
	}

	public void altera(LinhaPesquisa linhaPesquisa, List<String> membros) {
		validaCamposObrigatorios(linhaPesquisa);
		validator.onErrorUsePageOf(this).form();

		dao.altera(linhaPesquisa);

		List<Membro> membrosAntigos = membroDao
				.findByResearchLine(linhaPesquisa.getId());

		// desmarcas os antigos
		for (Membro membro : membrosAntigos) {
			if (foiDesmarcado(membro, membros)) {
				membro.setLinhaPesquisa(null);
				membroDao.altera(membro);
			}
		}

		// marca os novos
		for (String id : membros) {
			Integer membroId = Integer.parseInt(id);
			if (ehMembroNovo(membroId, membrosAntigos)) {
				Membro membro = membroDao.carrega(membroId);
				membro.setLinhaPesquisa(linhaPesquisa);
				membroDao.altera(membro);
			}
		}

		result.include("mensagem", "linha_alterada");
		result.redirectTo(this).index(null);
	}

	private boolean ehMembroNovo(Integer membroId, List<Membro> membrosAntigos) {
		for (Membro membroAntigo : membrosAntigos) {
			if (membroId == membroAntigo.getId()) {
				return false;
			}
		}
		return true;
	}

	private boolean foiDesmarcado(Membro membro, List<String> membros) {
		for (String id : membros) {
			if (Integer.parseInt(id) == membro.getId()) {
				return false;
			}
		}
		return true;
	}

	private void validaCamposObrigatorios(LinhaPesquisa linhaPesquisa) {
		if (linhaPesquisa.getTitulo().isEmpty()) {
			validator.add(new ValidationMessage("erro",
					"linhaPesquisa_titulo_branco"));
		}
		if (linhaPesquisa.getSumario().isEmpty()) {
			validator.add(new ValidationMessage("erro",
					"linhaPesquisa_sumario_branco"));
		}
	}

	public LinhaPesquisa edita(LinhaPesquisa linhaPesquisa) {
		result.include("membroList", membroDao.findAll());
		return dao.carrega(linhaPesquisa.getId());
	}
}
